home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / programer2 / icon / Source / Icont / C / Tsym < prev    next >
Encoding:
Text File  |  1990-07-20  |  13.5 KB  |  546 lines

  1. /*
  2.  * tsym.c -- functions for symbol table management.
  3.  */
  4.  
  5. #include "../h/config.h"
  6. #include "general.h"
  7. #include "tproto.h"
  8. #include "globals.h"
  9. #include "trans.h"
  10. #include "token.h"
  11. #include "tsym.h"
  12.  
  13. #ifndef VarTran
  14. #include "lfile.h"
  15. #endif                    /* VarTran */
  16.  
  17. /*
  18.  * Prototypes.
  19.  */
  20.  
  21. hidden struct    tgentry *alcglob
  22.    Params((struct tgentry *blink, char *name,int flag,int nargs));
  23. hidden struct    tientry *alcid        Params((char *nam,int len));
  24. hidden struct    tcentry *alclit    
  25.    Params((struct tcentry *blink, char *name, int len,int flag));
  26. hidden struct    tlentry *alcloc    
  27.    Params((struct tlentry *blink, char *name,int flag));
  28. hidden struct    tcentry *clookup    Params((char *id,int flag));
  29. hidden struct    tgentry *glookup    Params((char *id));
  30. hidden struct    tlentry *llookup    Params((char *id));
  31. hidden novalue    putglob
  32.    Params((char *id,int id_type, int n_args));
  33. hidden int    streq            Params((int len,char *s1,char *s2));
  34.  
  35. #ifdef DeBugTrans
  36. novalue    cdump    Params((noargs));
  37. novalue    gdump    Params((noargs));
  38. novalue    ldump    Params((noargs));
  39. #endif                    /* DeBugTrans */
  40.  
  41.  
  42. /*
  43.  * putid - install the identifier named by the string starting at strf
  44.  *  and extending for len bytes.  The installation entails making an
  45.  *  entry in the identifier hash table and then making an identifier
  46.  *  table entry for it with alcid.  A side effect of installation
  47.  *  is the incrementing of strf by the length of the string, thus
  48.  *  "saving" it.
  49.  *
  50.  * Nothing is changed if the identifier has already been installed.
  51.  */
  52. char *putid(len)
  53. int len;
  54.    {
  55.    register int hash;
  56.    register char *s;
  57.    register struct tientry *ip;
  58.    int l;
  59.  
  60.    /*
  61.     * Compute hash value by adding bytes and masking result with imask.
  62.     *  (Recall that imask is ihsize-1.)
  63.     */
  64.    s = strf;
  65.    hash = 0;
  66.    l = len;
  67.    while (l--)
  68.       hash += *s++ & 0377;
  69.    s = strf;
  70.    l = len;
  71.    hash &= imask;
  72.    /*
  73.     * If the identifier hasn't been installed, install it.
  74.     */
  75.    if ((ip = ihash[hash]) != NULL) {    /* collision */
  76.       for (;;) {    /* work down i_blink chain until id is found or the
  77.                             end of the chain is reached */
  78.          if (l == ip->i_length && streq(l, s, ip->i_name))
  79.             return (ip->i_name);    /* id is already installed */
  80.          if (ip->i_blink == NULL) {    /* end of chain */
  81.             ip->i_blink = alcid(s,l);
  82.             strf += l;
  83.             return s;
  84.             }
  85.          ip = ip->i_blink;
  86.          }
  87.       }
  88.    /*
  89.     * Hashed to an empty slot.
  90.     */
  91.    ihash[hash] = alcid(s,l);
  92.    strf += l;
  93.    return s;
  94.    }
  95.  
  96. /*
  97.  * streq - compare s1 with s2 for len bytes, and return 1 for equal,
  98.  *  0 for not equal.
  99.  */
  100. static int streq(len, s1, s2)
  101. register int len;
  102. register char *s1, *s2;
  103.    {
  104.    while (len--)
  105.       if (*s1++ != *s2++)
  106.          return 0;
  107.    return 1;
  108.    }
  109.  
  110. /*
  111.  * alcid - get the next free identifier table entry, and fill it in with
  112.  *  the specified values.
  113.  */
  114. static struct tientry *alcid(nam, len)
  115. char *nam;
  116. int len;
  117.    {
  118.    register struct tientry *ip;
  119.  
  120.    if (ifree >= &itable[isize])
  121.       tsyserr("out of identifier table space");
  122.    ip = ifree++;
  123.    ip->i_blink = NULL;
  124.    ip->i_name = nam;
  125.    ip->i_length = len;
  126.    return ip;
  127.    }
  128.  
  129. #ifndef VarTran
  130.  
  131. /*
  132.  * loc_init - clear the local symbol table.
  133.  */
  134.  
  135. novalue loc_init()
  136.    {
  137.    register struct tlentry **lp;
  138.    register struct tcentry **cp;
  139.    static int maxlfree = 0;
  140.    static int maxcfree = 0;
  141.                     /* clear local table */
  142.    maxlfree = (maxlfree > lfree-ltable) ? maxlfree : lfree-ltable;
  143.    for (lp = lhash; lp < &lhash[lhsize]; lp++)
  144.       *lp = NULL;
  145.    lfree = ltable;
  146.                     /* clear constant table */
  147.    maxcfree = (maxcfree > ctfree-ctable) ? maxcfree : ctfree-ctable;
  148.    for (cp = chash; cp < &chash[chsize]; cp++)
  149.       *cp = NULL;
  150.    ctfree = ctable;
  151.    }
  152.  
  153. /*
  154.  * install - put an identifier into the global or local symbol table.
  155.  *  The basic idea here is to look in the right table and install
  156.  *  the identifier if it isn't already there.  Some semantic checks
  157.  *  are performed.
  158.  */
  159. novalue install(name, flag, argcnt)
  160. char *name;
  161. int flag, argcnt;
  162.    {
  163.    union {
  164.       struct tgentry *gp;
  165.       struct tlentry *lp;
  166.       } p;
  167.  
  168.    switch (flag) {
  169.       case F_Global:    /* a variable in a global declaration */
  170.          if ((p.gp = glookup(name)) == NULL)
  171.             putglob(name, flag, argcnt);
  172.          else
  173.             p.gp->g_flag |= flag;
  174.          break;
  175.  
  176.       case F_Proc|F_Global:    /* procedure declaration */
  177.       case F_Record|F_Global:    /* record declaration */
  178.       case F_Builtin|F_Global:    /* external declaration */
  179.          if ((p.gp = glookup(name)) == NULL)
  180.             putglob(name, flag, argcnt);
  181.          else if ((p.gp->g_flag & (~F_Global)) == 0) { /* superfluous global
  182.                                declaration for
  183.                                record or proc */
  184.             p.gp->g_flag |= flag;
  185.             p.gp->g_nargs = argcnt;
  186.             }
  187.          else            /* the user can't make up his mind */
  188.             tfatal("inconsistent redeclaration", name);
  189.          break;
  190.  
  191.       case F_Static:    /* static declaration */
  192.       case F_Dynamic:    /* local declaration (possibly implicit?) */
  193.       case F_Argument:    /* formal parameter */
  194.          if ((p.lp = llookup(name)) == NULL)
  195.             putloc(name,flag);
  196.          else if (p.lp->l_flag == flag) /* previously declared as same type */
  197.             tfatal("redeclared identifier", name);
  198.          else        /* previously declared as different type */
  199.             tfatal("inconsistent redeclaration", name);
  200.          break;
  201.  
  202.       default:
  203.          tsyserr("install: unrecognized symbol table flag.");
  204.       }
  205.    }
  206.  
  207. /*
  208.  * putloc - make a local symbol table entry and return the index
  209.  *  of the entry in lhash.  alcloc does the work if there is a collision.
  210.  */
  211. int putloc(id,id_type)
  212. char *id;
  213. int id_type;
  214.    {
  215.    register struct tlentry *ptr;
  216.  
  217.    if ((ptr = llookup(id)) == NULL) {    /* add to head of hash chain */
  218.       ptr = lhash[lhasher(id)];
  219.       lhash[lhasher(id)] = alcloc(ptr, id, id_type);
  220.       return (lhash[lhasher(id)] - ltable);
  221.       }
  222.    return (ptr - ltable);
  223.    }
  224.  
  225. /*
  226.  * putglob makes a global symbol table entry. alcglob does the work if there
  227.  *  is a collision.
  228.  */
  229.  
  230. static novalue putglob(id, id_type, n_args)
  231. char *id;
  232. int id_type, n_args;
  233.    {
  234.    register struct tgentry *ptr;
  235.  
  236.    if ((ptr = glookup(id)) == NULL) {     /* add to head of hash chain */
  237.       ptr = ghash[ghasher(id)];
  238.       ghash[ghasher(id)] = alcglob(ptr, id, id_type, n_args);
  239.       }
  240.    }
  241.  
  242. /*
  243.  * putlit makes a constant symbol table entry and returns the index
  244.  *  of the entry in chash.  alclit does the work if there is a collision.
  245.  */
  246. int putlit(id, idtype, len)
  247. char *id;
  248. int len, idtype;
  249.    {
  250.    register struct tcentry *ptr;
  251.  
  252.    if ((ptr = clookup(id,idtype)) == NULL) {   /* add to head of hash chain */
  253.       ptr = chash[chasher(id)];
  254.       chash[chasher(id)] = alclit(ptr, id, len, idtype);
  255.       return (chash[chasher(id)] - ctable);
  256.       }
  257.    return (ptr - ctable);
  258.    }
  259.  
  260. /*
  261.  * llookup looks up id in local symbol table and returns pointer to
  262.  *  to it if found or NULL if not present.
  263.  */
  264.  
  265. static struct tlentry *llookup(id)
  266. char *id;
  267.    {
  268.    register struct tlentry *ptr;
  269.  
  270.    ptr = lhash[lhasher(id)];
  271.    while (ptr != NULL && ptr->l_name != id)
  272.       ptr = ptr->l_blink;
  273.    return ptr;
  274.    }
  275.  
  276. /*
  277.  * glookup looks up id in global symbol table and returns pointer to
  278.  *  to it if found or NULL if not present.
  279.  */
  280. static struct tgentry *glookup(id)
  281. char *id;
  282.    {
  283.    register struct tgentry *ptr;
  284.  
  285.    ptr = ghash[ghasher(id)];
  286.    while (ptr != NULL && ptr->g_name != id) {
  287.       ptr = ptr->g_blink;
  288.       }
  289.    return ptr;
  290.    }
  291.  
  292. /*
  293.  * clookup looks up id in constant symbol table and returns pointer to
  294.  *  to it if found or NULL if not present.
  295.  */
  296. static struct tcentry *clookup(id,flag)
  297. char *id;
  298. int flag;
  299.    {
  300.    register struct tcentry *ptr;
  301.  
  302.    ptr = chash[chasher(id)];
  303.    while (ptr != NULL && (ptr->c_name != id || ptr->c_flag != flag))
  304.       ptr = ptr->c_blink;
  305.  
  306.    return ptr;
  307.    }
  308.  
  309. /*
  310.  * klookup looks up keyword named by id in keyword table and returns
  311.  *  its number (keyid).
  312.  */
  313. int klookup(id)
  314. register char *id;
  315.    {
  316.    register struct keyent *kp;
  317.  
  318.    for (kp = keytab; kp->keyid >= 0; kp++)
  319.       if (strcmp(kp->keyname,id) == 0)
  320.          return (kp->keyid);
  321.  
  322.    return 0;
  323.    }
  324.  
  325. #ifdef DeBugTrans
  326. /*
  327.  * ldump displays local symbol table to stdout.
  328.  */
  329.  
  330. novalue ldump()
  331.    {
  332.    register int i;
  333.    register struct tlentry *lptr;
  334.  
  335.    fprintf(stderr,"Dump of local symbol table (%d entries)\n",lfree-ltable);
  336.    fprintf(stderr," loc   blink   id          (name)      flags\n");
  337.    for (i = 0; i < lhsize; i++)
  338.       for (lptr = lhash[i]; lptr != NULL; lptr = lptr->l_blink)
  339.          fprintf(stderr,"%5d  %5d  %5d    %20s  %7o\n", lptr-ltable,
  340.         lptr->l_blink, lptr->l_name, lptr->l_name, lptr->l_flag);
  341.    fflush(stderr);
  342.  
  343.    }
  344.  
  345. /*
  346.  * gdump displays global symbol table to stdout.
  347.  */
  348.  
  349. novalue gdump()
  350.    {
  351.    register int i;
  352.    register struct tgentry *gptr;
  353.  
  354.    fprintf(stderr,"Dump of global symbol table (%d entries)\n",
  355.       (int)(gfree-gtable));
  356.    fprintf(stderr," loc   blink   id          (name)      flags      nargs\n");
  357.    for (i = 0; i < ghsize; i++)
  358.       for (gptr = ghash[i]; gptr != NULL; gptr = gptr->g_blink)
  359.          fprintf(stderr,"%5d  %5d  %5d    %20s  %7o   %8d\n", gptr-gtable,
  360.         gptr->g_blink, gptr->g_name, gptr->g_name,
  361.         gptr->g_flag, gptr->g_nargs);
  362.    fflush(stderr);
  363.    }
  364.  
  365. /*
  366.  * cdump displays constant symbol table to stdout.
  367.  */
  368.  
  369. novalue cdump()
  370.    {
  371.    register int i;
  372.    register struct tcentry *cptr;
  373.  
  374.    fprintf(stderr,"Dump of constant symbol table (%d entries)\n",ctfree-ctable);
  375.    fprintf(stderr," loc   blink   id          (name)      flags\n");
  376.    for (i = 0; i < chsize; i++)
  377.       for (cptr = chash[i]; cptr != NULL; cptr = cptr->c_blink)
  378.          fprintf(stderr,"%5d  %5d  %5d    %20s  %7o\n", cptr-ctable,
  379.         cptr->c_blink, cptr->c_name, cptr->c_name, cptr->c_flag);
  380.    fflush(stderr);
  381.    }
  382. #endif                    /* DeBugTrans */
  383.  
  384. /*
  385.  * alcloc allocates a local symbol table entry, fills in fields with
  386.  *  specified values and returns offset of new entry.  
  387.  */
  388. static struct tlentry *alcloc(blink, name, flag)
  389. struct tlentry *blink;
  390. char *name;
  391. int flag;
  392.    {
  393.    register struct tlentry *lp;
  394.  
  395.    if (lfree >= <able[lsize])
  396.       tsyserr("out of local symbol table space");
  397.    lp = lfree++;
  398.    lp->l_blink = blink;
  399.    lp->l_name = name;
  400.    lp->l_flag = flag;
  401.    return lp;
  402.    }
  403.  
  404. /*
  405.  * alcglob allocates a global symbol table entry, fills in fields with
  406.  *  specified values and returns offset of new entry.  
  407.  */
  408. static struct tgentry *alcglob(blink, name, flag, nargs)
  409. struct tgentry *blink;
  410. char *name;
  411. int flag, nargs;
  412.    {
  413.    register struct tgentry *gp;
  414.  
  415.    if (gfree >= >able[gsize])
  416.       tsyserr("out of global symbol table space");
  417.    gp = gfree++;
  418.    gp->g_blink = blink;
  419.    gp->g_name = name;
  420.    gp->g_flag = flag;
  421.    gp->g_nargs = nargs;
  422.    return gp;
  423.    }
  424.  
  425. /*
  426.  * alclit allocates a constant symbol table entry, fills in fields with
  427.  *  specified values and returns offset of new entry.  
  428.  */
  429. static struct tcentry *alclit(blink, name, len, flag)
  430. struct tcentry *blink;
  431. char *name;
  432. int len, flag;
  433.    {
  434.    register struct tcentry *cp;
  435.  
  436.    if (ctfree >= &ctable[csize])
  437.       tsyserr("out of constant table space");
  438.    cp = ctfree++;
  439.    cp->c_blink = blink;
  440.    cp->c_name = name;
  441.    cp->c_length = len;
  442.    cp->c_flag = flag;
  443.    return cp;
  444.    }
  445.  
  446. /*
  447.  * lout dumps local symbol table to fd, which is a .u1 file.
  448.  */
  449. novalue lout(fd)
  450. FILE *fd;
  451.    {
  452.    register int i;
  453.    register struct tlentry *lp;
  454.  
  455.    i = 0;
  456.    for (lp = ltable; lp < lfree; lp++)
  457.       writecheck(fprintf(fd, "\tlocal\t%d,%06o,%s\n",
  458.          i++, lp->l_flag, lp->l_name));
  459.    }
  460.  
  461. /*
  462.  * cout dumps constant symbol table to fd, which is a .u1 file.
  463.  */
  464. novalue cout(fd)
  465. FILE *fd;
  466.    {
  467.    register int l;
  468.    register char *c;
  469.    register struct tcentry *cp;
  470.    int i;
  471.  
  472.    i = 0;
  473.    for (cp = ctable; cp < ctfree; cp++) {
  474.       writecheck(fprintf(fd, "\tcon\t%d,%06o", i++, cp->c_flag));
  475.       if (cp->c_flag & F_IntLit)
  476.          writecheck(fprintf(fd, ",%d,%s\n", strlen(cp->c_name), cp->c_name));
  477.       else if (cp->c_flag & F_RealLit)
  478.          writecheck(fprintf(fd, ",%s\n", cp->c_name));
  479.       else {
  480.          c = cp->c_name;
  481.          l = cp->c_length - 1;
  482.          writecheck(fprintf(fd, ",%d", l));
  483.          while (l--)
  484.             writecheck(fprintf(fd, ",%03o", *c++ & 0377));
  485.          writecheck(putc('\n', fd));
  486.          }
  487.       }
  488.    }
  489.  
  490. /*
  491.  * rout dumps a record declaration for name to file fd, which is a .u2 file.
  492.  */
  493. novalue rout(fd,name)
  494. FILE *fd;
  495. char *name;
  496.    {
  497.    register int i;
  498.    register struct tlentry *lp;
  499.  
  500.    writecheck(fprintf(fd, "record\t%s,%d\n", name, (int)(lfree-ltable)));
  501.    i = 0;
  502.    for (lp = ltable; lp < lfree; lp++)
  503.       writecheck(fprintf(fd, "\t%d,%s\n", i++, lp->l_name));
  504.    }
  505.  
  506. /*
  507.  * gout writes various items to fd, which is a .u2 file.  These items
  508.  *  include: implicit status, tracing activation, link directives,
  509.  *  and the global table.
  510.  */
  511. novalue gout(fd)
  512. FILE *fd;
  513.    {
  514.    register int i;
  515.    register char *name;
  516.    register struct tgentry *gp;
  517.    struct lfile *lfl;
  518.    
  519.    if (uwarn)
  520.       name = "error";
  521.    else
  522.       name = "local";
  523.    writecheck(fprintf(fd, "impl\t%s\n", name));
  524.    if (trace)
  525.       writecheck(fprintf(fd, "trace\n"));
  526.    
  527.    lfl = lfiles;
  528.    while (lfl) {
  529.  
  530. #if MVS
  531.       writecheck(fprintf(fd,"link\t%s\n",lfl->lf_name));
  532. #else                    /* MVS */
  533.       writecheck(fprintf(fd,"link\t%s.u1\n",lfl->lf_name));
  534. #endif                    /* MVS */
  535.  
  536.       lfl = lfl->lf_link;
  537.       }
  538.    lfiles = 0;
  539.    writecheck(fprintf(fd, "global\t%d\n", (int)(gfree-gtable)));
  540.    i = 0;
  541.    for (gp = gtable; gp < gfree; gp++)
  542.       writecheck(fprintf(fd, "\t%d,%06o,%s,%d\n", i++, gp->g_flag,
  543.          gp->g_name, gp->g_nargs));
  544.    }
  545. #endif                    /* VarTran */
  546.